package cn.stylefeng.guns.modular.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.stylefeng.guns.modular.business.comment.YunHeKey;
import cn.stylefeng.guns.modular.business.entity.SubBookInfo;
import cn.stylefeng.guns.modular.business.entity.SubFileInfo;
import cn.stylefeng.guns.modular.business.enums.SubBookInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.enums.SubDrawInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.SubBookInfoMapper;
import cn.stylefeng.guns.modular.business.pojo.SubBookInfoRequest;
import cn.stylefeng.guns.modular.business.pojo.SubFileInfoRequest;
import cn.stylefeng.guns.modular.business.service.SubBookInfoService;
import cn.stylefeng.guns.modular.business.service.SubFileInfoService;
import cn.stylefeng.guns.modular.business.service.SubUseBrowseService;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 图书数据业务实现层
 *
 * @author zhangyaowen
 * @date 2021/08/18 14:09
 */
@Service
public class SubBookInfoServiceImpl extends ServiceImpl<SubBookInfoMapper, SubBookInfo> implements SubBookInfoService {

    @Resource
    private SubFileInfoService subFileInfoService;
    @Resource
    private LoginUserApi loginUserApi;
    @Resource
    private SubUseBrowseService subUseBrowseService;

	@Override
    public void add(SubBookInfoRequest subBookInfoRequest) {
        SubBookInfo subBookInfo = new SubBookInfo();
        BeanUtil.copyProperties(subBookInfoRequest, subBookInfo);
        this.save(subBookInfo);
    }

    @Override
    public void del(SubBookInfoRequest subBookInfoRequest) {
        SubBookInfo subBookInfo = this.querySubBookInfo(subBookInfoRequest);
        this.removeById(subBookInfo.getId());
    }

    @Override
    public void edit(SubBookInfoRequest subBookInfoRequest) {
        SubBookInfo subBookInfo = this.querySubBookInfo(subBookInfoRequest);
        BeanUtil.copyProperties(subBookInfoRequest, subBookInfo);
        this.updateById(subBookInfo);
    }

    @Override
    public SubBookInfo detail(SubBookInfoRequest subBookInfoRequest) {
        return this.querySubBookInfo(subBookInfoRequest);
    }

    @Override
    public PageResult<Map<String, Object>> findPage(SubBookInfoRequest subBookInfoRequest) {
        LambdaQueryWrapper<SubBookInfo> queryWrapper = new LambdaQueryWrapper<>();

        String bookName = subBookInfoRequest.getBookName();
        String chiefEditor = subBookInfoRequest.getChiefEditor();
        String bookPublish = subBookInfoRequest.getBookPublish();

        queryWrapper.like(ObjectUtil.isNotEmpty(bookName), SubBookInfo::getBookName, bookName);
        queryWrapper.like(ObjectUtil.isNotEmpty(chiefEditor), SubBookInfo::getChiefEditor, chiefEditor);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookPublish), SubBookInfo::getBookNumber, bookPublish);

        Page<SubBookInfo> sysRolePage = this.page(PageFactory.defaultPage(), queryWrapper);

        PageResult<SubBookInfo> subBookInfoPageResult= PageResultFactory.createPageResult(sysRolePage);
        List<SubBookInfo> list = subBookInfoPageResult.getRows();
        PageResult<Map<String, Object>> pageResult = new PageResult<>();
        List<Map<String,Object>> mapList = new ArrayList<>();
        for(SubBookInfo subBookInfo : list){
            Map<String, Object> map = new HashMap<String, Object>();
            map = JSONObject.parseObject(JSONObject.toJSONString(subBookInfo), Map.class);
            map.remove("id");
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

            String jmid = YunHeKey.YHYD+subBookInfo.getId();
            String encryptHex = aes.encryptHex(jmid);
            map.put("id",encryptHex);
            SubFileInfoRequest subFileInfoRequest = new SubFileInfoRequest();
            subFileInfoRequest.setFileType(1L);
            subFileInfoRequest.setFileOriginName(map.get("bookName").toString());
            subFileInfoRequest.setFileFirstBelong(YunHeKey.YUEDU);
            List<SubFileInfo> subFileInfoPageResult = subFileInfoService.findIndexId(subFileInfoRequest);
            if(!subFileInfoPageResult.isEmpty()) {
                map.put("fileId", subFileInfoPageResult.get(0).getId());
            }

            mapList.add(map);
        }
        pageResult.setRows(mapList);
        pageResult.setPageNo(subBookInfoPageResult.getPageNo());
        pageResult.setTotalRows(subBookInfoPageResult.getTotalRows());
        pageResult.setPageSize(subBookInfoPageResult.getPageSize());
        pageResult.setTotalPage(subBookInfoPageResult.getTotalPage());
        return pageResult;
    }


    public List<Map<String,Object>> recommendBook(SubBookInfoRequest subBookInfoRequest) {
        LambdaQueryWrapper<SubBookInfo> queryWrapper = new LambdaQueryWrapper<>();

        Long bookRecommend = subBookInfoRequest.getBookRecommend();
        queryWrapper.eq(ObjectUtil.isNotEmpty(bookRecommend), SubBookInfo::getBookRecommend, bookRecommend);
        List<SubBookInfo> subBookInfoList = this.list(queryWrapper);
        List<Map<String,Object>> mapList = new ArrayList<>();
        for(SubBookInfo subBookInfo : subBookInfoList) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("bookName",subBookInfo.getBookName());
            map.put("contentSummary",subBookInfo.getContentSummary());
            SubFileInfoRequest subFileInfoRequest = new SubFileInfoRequest();
            subFileInfoRequest.setFileType(1L);
            subFileInfoRequest.setFileOriginName(map.get("bookName").toString());
            subFileInfoRequest.setFileFirstBelong(YunHeKey.YUEDU);
            PageResult<SubFileInfo> subFileInfoPageResult = subFileInfoService.findPage(subFileInfoRequest);
            map.put("fileId",subFileInfoPageResult.getRows().get(0).getId());
            mapList.add(map);
        }

        return mapList;
    }

    @Override
    public List<SubBookInfo> findList(SubBookInfoRequest subBookInfoRequest) {
        LambdaQueryWrapper<SubBookInfo> wrapper = this.createWrapper(subBookInfoRequest);
        return this.list(wrapper);
    }

    /**
     * 获取信息
     *
     * @author zhangyaowen
     * @date 2021/08/18 14:09
     */
    private SubBookInfo querySubBookInfo(SubBookInfoRequest subBookInfoRequest) {
        SubBookInfo subBookInfo = this.getById(subBookInfoRequest.getId());
        if (ObjectUtil.isEmpty(subBookInfo)) {
            throw new ServiceException(SubBookInfoExceptionEnum.SUBBOOKINFO_NOT_EXISTED);
        }
        return subBookInfo;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/18 14:09
     */
    private LambdaQueryWrapper<SubBookInfo> createWrapper(SubBookInfoRequest subBookInfoRequest) {
        LambdaQueryWrapper<SubBookInfo> queryWrapper = new LambdaQueryWrapper<>();

        Long id = subBookInfoRequest.getId();
        String bookName = subBookInfoRequest.getBookName();
        String chiefEditor = subBookInfoRequest.getChiefEditor();
        String bookPublish = subBookInfoRequest.getBookPublish();
        String bookNumber = subBookInfoRequest.getBookNumber();
        String bookPrice = subBookInfoRequest.getBookPrice();
        String bookSize = subBookInfoRequest.getBookSize();
        String bookSheet = subBookInfoRequest.getBookSheet();
        String publishTime = subBookInfoRequest.getPublishTime();
        String contentSummary = subBookInfoRequest.getContentSummary();
        String bookPath = subBookInfoRequest.getBookPath();

        queryWrapper.eq(ObjectUtil.isNotNull(id), SubBookInfo::getId, id);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookName), SubBookInfo::getBookName, bookName);
        queryWrapper.like(ObjectUtil.isNotEmpty(chiefEditor), SubBookInfo::getChiefEditor, chiefEditor);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookPublish), SubBookInfo::getBookPublish, bookPublish);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookNumber), SubBookInfo::getBookNumber, bookNumber);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookPrice), SubBookInfo::getBookPrice, bookPrice);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookSize), SubBookInfo::getBookSize, bookSize);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookSheet), SubBookInfo::getBookSheet, bookSheet);
        queryWrapper.like(ObjectUtil.isNotEmpty(publishTime), SubBookInfo::getPublishTime, publishTime);
        queryWrapper.like(ObjectUtil.isNotEmpty(contentSummary), SubBookInfo::getContentSummary, contentSummary);
        queryWrapper.like(ObjectUtil.isNotEmpty(bookPath), SubBookInfo::getBookPath, bookPath);

        return queryWrapper;
    }


    @Override
    public List<Map<String, Object>> toSubBookInfoReview(String  id) {
        byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        String decryptStr = aes.decryptStr(id, CharsetUtil.CHARSET_UTF_8);
        //获取ID字符串YD后面真实的的id
        String name = StrUtil.subAfter(decryptStr,YunHeKey.YHYD,false);
        HttpServletRequest request = HttpServletUtil.getRequest();
        Long userid ;
        if (ObjectUtil.isNotNull(request)) {

            LoginUser loginUser = loginUserApi.getLoginUser();
            userid = loginUser.getUserId();
        } else {
            throw new ServiceException(SubDrawInfoExceptionEnum.REQUEST_EMPTY);
        }
        LambdaQueryWrapper<SubBookInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(ObjectUtil.isNotEmpty(name), SubBookInfo::getId, name);
        List<SubBookInfo> subBookInfosList = this.list(queryWrapper);
        if(userid != 0l && userid != -1l) {
            subUseBrowseService.saveBrowse(YunHeKey.YUEDU,subBookInfosList.get(0).getBookName(),userid,request);
        }
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (SubBookInfo subBookInfo : subBookInfosList) {

            Map<String, Object> map = new HashMap<String, Object>();
            map = JSONObject.parseObject(JSONObject.toJSONString(subBookInfo), Map.class);

            // 获取类的属性
            Field[] declaredFields = SubBookInfo.class.getDeclaredFields();
            List<Map<String, Object>> mplist = new ArrayList<>();
            // 遍历属性，获取属性上ApiModelProperty的值，属性的名，存入Properties
            if (declaredFields.length != 0) {

                int i = 1;
                Map<String, Object> p = new HashMap<String, Object>();
                for (Field field : declaredFields) {

                    Map<String, Object> mp = new HashMap<String, Object>();
                    if (field.getAnnotation(ApiModelProperty.class) != null) {
                        //获取注解属性
                        ApiModelProperty aa = field.getAnnotation(ApiModelProperty.class);
                        // key和value可根据需求存
                        // 这存的key为注解的值，value为类属性名
//                        if (!"bookName".equals(field.getName())) {


                            if ("bookName".equals(field.getName()) || "contentSummary".equals(field.getName()) ) {
                                p.put(field.getName(), map.get(field.getName()));
                                if("bookName".equals(field.getName())){
                                    SubFileInfoRequest subFileInfoRequest = new SubFileInfoRequest();
                                    subFileInfoRequest.setFileType(2L);
                                    subFileInfoRequest.setFileOriginName(map.get(field.getName()).toString());
                                    subFileInfoRequest.setFileFirstBelong(YunHeKey.YUEDU);
                                    PageResult<SubFileInfo> subFileInfoPageResult = subFileInfoService.findPage(subFileInfoRequest);
                                    if(!subFileInfoPageResult.getRows().isEmpty()) {
                                        p.put("fileId", subFileInfoPageResult.getRows().get(0).getId());
                                    }
                                }
                            } else {
                                mp.put("key", aa.value());
                                mp.put("value", map.get(field.getName()));

                                if (i != 1) {
                                    mplist.add(mp);
                                }
                            }
//                        }
                    }
                    i++;
                }
                p.put("list", mplist);
                if (i != 1) {
                    mapList.add(p);
                }
            }
        }
        return mapList;
    }
}